class Node:
    def __init__(self):
        self.data = None
        self.next = None
        self.prev = None
# 定义数据属性，self.data 为数据内容；self.next 为下一个数据的地址信息； self.prev 为上一个数据的位置信息


class Link:
    def __init__(self, data=()):          # data为引入的list参数
        self.head = Node()                # 定义初始位置head
        self.tail = self.head             # self.tail 为最后一个位置
        self.length = 0
        for d in data:
            self.append(d)                # 将传入的data列表数据append到self

    def __find_node_by(self, pos):        # 找下标
        nodeptr = self.head
        while pos:                        # pos 为传入的位置参数
            nodeptr = nodeptr.next        # 以head位置为基准，每循环一次跳到下个位置的值
            pos -= 1                      # 位置参数减1，直到减为0，即跳出循环，取到第pos个位置的信息
        return nodeptr

    def append(self, data):               #
        node = Node()
        node.data = data
        self.tail.next = node             # 定义要append的数据为node，位置在self.tail的next
        node.prev = self.tail             # 定义其前一个位置为self.tail
        self.tail = node                  # 将当前的node（即append的data 定义为self.tail）
        self.length += 1                  # self的长度加1

    def pop(self, i=-1):
        if len(self) <= 0:                # 如果长度小于等于0 判定为empty，调用len方法
            raise Exception("The list is empty")

        if i == -1:
            node = self.tail              # node为最后一个
            self.tail = node.prev         # 定义node.prev 为最后一个
            self.tail.next = None         # node.pre 的next为none
            self.length -= 1
            return node.data
        else:
            node = self.__find_node_by(i)
            cur_node = node.next
            third_node = node.next.next
            if third_node is not None:    # node后的第二个不为空，则令其后第二个前向指向node，忽略node后的第一个
                third_node.prev = node
            node.next = third_node        # node后的第二个为空，即令node的下一个为空
            self.length -= 1
            return cur_node.data

    def insert(self, i, data):
        assert i <= len(self) - 1
        nodeptr = self.head
        while i:
            nodeptr = nodeptr.next
            i -= 1

        third_node = nodeptr.next
        node = Node()
        node.data = data

        node.next = third_node
        third_node.prev = node

        nodeptr.next = node
        node.prev = nodeptr
        self.length += 1

    def remove(self, i):
        assert i <= len(self) - 1
        nodeptr = self.__find_node_by(i)
        third_node = nodeptr.next.next
        nodeptr.next = third_node
        third_node.prev = nodeptr
        self.length -= 1

# ______________________ add_equal ______________________
    def add_equal(self, data):
        self_node_tail = self.tail
        new_node_head = data.head
        self_node_tail.next = new_node_head.next
        new_node_head.prev = self_node_tail.prev
        return self

# _________________________add_______________________________

    def adds(self, data1, data2):
        for i in data1:
            self.append(i)
        self_node_tail = data1.tail
        data2_head = data2.head
        self_node_tail.next = data2_head.next
        data2_head.prev = self_node_tail.prev
        return self

# _________________________________________________________


    def __len__(self):
        return self.length                 # 定义len方法

    def __iter__(self):
        return LinkIterator(self)

    def __setitem__(self, key, value):
        raise NotImplementedError

    def __getitem__(self, item):
        assert item <= len(self) - 1
        nodeptr = self.head.next
        while item:
            nodeptr = nodeptr.next
            item -= 1

        return nodeptr.data

    def __contains__(self, item):
        print('__contain__ is used')
        for d in self:
            if d == item:
                return True
        return False

    def __str__(self):
        return str([i for i in self])


class LinkIterator:
    def __init__(self, link):
        self._node_ptr = link.head

    def __next__(self):
        self._node_ptr = self._node_ptr.next
        if self._node_ptr is None:
            raise StopIteration
        data = self._node_ptr.data
        return data



# x = list()
# x.append(1)
# x.append(2)
# x.append(3)
# print(x)

# while x:
#     print(x.pop())

# x[0] = 1
# y = x[0]
#
# for d in x:
#     for y in x:
#         print(y)


# x.insert(1, 8)
# for d in x:
#     print(d)
#
# print("\n")
# x.remove(1)
# for d in x:
#     print(d)

# if 2 in x:
#     print("2 is in list")
#
# print("The 2th is: %d" % x[1])
x = Link((1, 2, 3))
y = Link((4, 5, 6))
z = x.add_equal(y)
print(Link().adds(x, y))
print(z)


